babl: refactor conversion dispatch to do less branches at runtime
authorØyvind Kolås <pippin@gimp.org>
Sun, 14 Jan 2018 17:36:26 +0000 (18:36 +0100)
committerØyvind Kolås <pippin@gimp.org>
Sun, 14 Jan 2018 17:45:46 +0000 (18:45 +0100)
babl/babl-conversion.c
babl/babl-conversion.h
babl/babl-internal.h

index 97955e265573db6cb3bcaa735b16fe80b2a6048f..78a5f1fa9d712cd329d8df2c617e0ee2559e207c 100644 (file)
@@ -34,6 +34,114 @@ static int model_is_rgba (const Babl *model)
   return 0;
 }
 
+
+static void
+babl_conversion_plane_process (BablConversion *conversion,
+                               const void     *source,
+                               void           *destination,
+                               int             src_pitch,
+                               int             dst_pitch,
+                               long            n,
+                               void           *user_data)
+{
+  conversion->function.plane ((void*)conversion, source, destination,
+                              src_pitch, dst_pitch,
+                              n,
+                              user_data);
+}
+
+static void
+babl_conversion_planar_process (const Babl *babl,
+                                const char     *src,
+                                char           *dst,
+                                long            n,
+                                void           *user_data)
+{
+  BablConversion *conversion = (void*)babl;
+  const BablImage *source = (void*)src;
+  BablImage       *destination = (void*)dst;
+#ifdef USE_ALLOCA
+  const char **src_data = alloca (sizeof (void *) * source->components);
+  char **dst_data = alloca (sizeof (void *) * destination->components);
+#else
+  const char  *src_data[BABL_MAX_COMPONENTS];
+  char  *dst_data[BABL_MAX_COMPONENTS];
+#endif
+
+  memcpy (src_data, source->data, sizeof (void *) * source->components);
+  memcpy (dst_data, destination->data, sizeof (void *) * destination->components);
+  conversion->function.planar ((void*)conversion,
+                                      source->components,
+                                      src_data,
+                                      source->pitch,
+                                      destination->components,
+                                      dst_data,
+                                      destination->pitch,
+                                      n,
+                                      user_data);
+}
+
+static void dispatch_plane (const Babl *babl,
+                            const char *source,
+                            char *destination,
+                            long n,
+                            void *user_data)
+{
+  const BablConversion *conversion = &babl->conversion;
+  const void *src_data  = NULL;
+  void *dst_data  = NULL;
+  int   src_pitch = 0;
+  int   dst_pitch = 0;
+
+  if (BABL_IS_BABL (source))
+    {
+      BablImage *img;
+
+      img       = (BablImage *) source;
+      src_data  = img->data[0];
+      src_pitch = img->pitch[0];
+    }
+  if (BABL_IS_BABL (destination))
+    {
+      BablImage *img = (BablImage *) destination;
+
+      dst_data  = img->data[0];
+      dst_pitch = img->pitch[0];
+    }
+
+  if (!src_data)
+    src_data = source;
+  if (!src_pitch)
+    src_pitch = BABL (conversion->source)->type.bits / 8;
+  if (!dst_data)
+    dst_data = destination;
+  if (!dst_pitch)
+    dst_pitch = BABL (conversion->destination)->type.bits / 8;
+
+  babl_conversion_plane_process ((void*)conversion,
+                                 src_data, dst_data,
+                                 src_pitch, dst_pitch,
+                                 n, user_data);
+}
+
+static inline void
+babl_conversion_rig_dispatch (const Babl *babl)
+{
+  BablConversion *conversion = (BablConversion *) babl;
+  switch (BABL (conversion)->class_type)
+  {
+    case BABL_CONVERSION_PLANE:
+      conversion->dispatch = dispatch_plane;
+      break;
+    case BABL_CONVERSION_PLANAR:
+      conversion->dispatch = babl_conversion_planar_process;
+      break;
+    case BABL_CONVERSION_LINEAR:
+      conversion->dispatch = conversion->function.linear;
+      break;
+  }
+}
+
 Babl *
 _conversion_new (const char    *name,
                  int            id,
@@ -144,6 +252,7 @@ _conversion_new (const char    *name,
       babl->conversion.error = 0.0;
     }
 
+  babl_conversion_rig_dispatch (babl);
   return babl;
 }
 
@@ -432,4 +541,6 @@ const Babl *babl_conversion_get_destination_space (const Babl *conversion)
   return conversion->conversion.destination->format.space;
 }
 
+
+
 BABL_CLASS_IMPLEMENT (conversion)
index d3fb09a5e3d1ed34c385fea72e5970565fa1a228..25bbeea25d8018d4917e89fa7438f4caf70a4eea 100644 (file)
@@ -42,6 +42,9 @@ _BablConversion {
   BablInstance           instance;
   const Babl            *source;
   const Babl            *destination;
+  void (*dispatch) (const Babl *babl, const char *src, char *dst, long n,
+                    void           *user_data);
+
   long                   cost;
   double                 error;
   union
index 3c08ff2ade344c46026b0d74fc3dff12001dfd12..337541bfc2528a8067f32fccb75d5c2f4179cf22 100644 (file)
@@ -482,56 +482,6 @@ void babl_space_to_xyz   (const Babl *space, const double *rgb, double *xyz);
  */
 void babl_space_from_xyz (const Babl *space, const double *xyz, double *rgb);
 
-static inline void
-babl_conversion_linear_process (BablConversion *conversion,
-                                const void     *source,
-                                void           *destination,
-                                long            n)
-{
-  conversion->function.linear ((void*)conversion, source, destination, n, conversion->data);
-}
-
-static inline void
-babl_conversion_plane_process (BablConversion *conversion,
-                               const void     *source,
-                               void           *destination,
-                               int             src_pitch,
-                               int             dst_pitch,
-                               long            n)
-{
-  conversion->function.plane ((void*)conversion, source, destination,
-                              src_pitch, dst_pitch,
-                              n,
-                              conversion->data);
-}
-
-static inline void
-babl_conversion_planar_process (BablConversion *conversion,
-                                BablImage      *source,
-                                BablImage      *destination,
-                                long            n)
-{
-#ifdef USE_ALLOCA
-  const char **src_data = alloca (sizeof (void *) * source->components);
-  char **dst_data = alloca (sizeof (void *) * destination->components);
-#else
-  const char  *src_data[BABL_MAX_COMPONENTS];
-  char  *dst_data[BABL_MAX_COMPONENTS];
-#endif
-
-  memcpy (src_data, source->data, sizeof (void *) * source->components);
-  memcpy (dst_data, destination->data, sizeof (void *) * destination->components);
-  conversion->function.planar ((void*)conversion,
-                                      source->components,
-                                      src_data,
-                                      source->pitch,
-                                      destination->components,
-                                      dst_data,
-                                      destination->pitch,
-                                      n,
-                                      conversion->data);
-}
-
 
 static inline void
 babl_conversion_process (const Babl *babl,
@@ -540,81 +490,9 @@ babl_conversion_process (const Babl *babl,
                          long        n)
 {
   BablConversion *conversion = (BablConversion *) babl;
-
-  // babl_assert (BABL_IS_BABL (conversion));
-
-  switch (BABL (conversion)->class_type)
-    {
-      case BABL_CONVERSION_PLANE:
-      {
-        const void *src_data  = NULL;
-        void *dst_data  = NULL;
-        int   src_pitch = 0;
-        int   dst_pitch = 0;
-
-        if (BABL_IS_BABL (source))
-          {
-            BablImage *img;
-
-            img       = (BablImage *) source;
-            src_data  = img->data[0];
-            src_pitch = img->pitch[0];
-          }
-        if (BABL_IS_BABL (destination))
-          {
-            BablImage *img = (BablImage *) destination;
-
-            dst_data  = img->data[0];
-            dst_pitch = img->pitch[0];
-          }
-
-        if (!src_data)
-          src_data = source;
-        if (!src_pitch)
-          src_pitch = BABL (conversion->source)->type.bits / 8;
-        if (!dst_data)
-          dst_data = destination;
-        if (!dst_pitch)
-          dst_pitch = BABL (conversion->destination)->type.bits / 8;
-
-        babl_conversion_plane_process (conversion,
-                                       src_data, dst_data,
-                                       src_pitch, dst_pitch,
-                                       n);
-      }
-        break;
-
-      case BABL_CONVERSION_PLANAR:
-        babl_assert (BABL_IS_BABL (source));
-        babl_assert (BABL_IS_BABL (destination));
-
-        babl_conversion_planar_process (conversion,
-                                        (BablImage *) source,
-                                        (BablImage *) destination,
-                                        n);
-        break;
-
-      case BABL_CONVERSION_LINEAR:
-        /* the assertions relied on a babl_malloc structure
-         *
-         * babl_assert (!BABL_IS_BABL (source));
-           babl_assert (!BABL_IS_BABL (destination));*/
-
-        babl_conversion_linear_process (conversion,
-                                        source,
-                                        destination,
-                                        n);
-        break;
-
-      default:
-        babl_log ("args=(%s, %p, %p, %li) unhandled conversion type: %s",
-                  conversion->instance.name, source, destination, n,
-                  babl_class_name (conversion->instance.class_type));
-        break;
-    }
-
   conversion->processings++;
   conversion->pixels += n;
+  conversion->dispatch (babl, source, destination, n, conversion->data);
 }
 
 #endif